package com.ccplay.dataservice.web;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.util.StringUtils;

import com.google.gson.JsonObject;
import com.oxygen.constants.Constant;
import com.oxygen.dto.ApiFinalResponse;
import com.oxygen.enums.ApiMethodEnum;
import com.oxygen.enums.ApiMsgEnum;
import com.oxygen.enums.ApiServerEnum;
import com.oxygen.util.HttpClientUtil;
import com.oxygen.util.JsonUtil;
import com.oxygen.util.RegexUtil;
import com.oxygen.web.SuperDispatcherServlet;
import com.oxygen.web.WebHelper;

public class BaseAction extends UploadBaseAction {

	protected static final String defaultApiKey = "android_client";

	@Value("${ccplay.user.api.server}")
	private String ccplayUserApiServer;

	@Value("${ccplay.content.api.server}")
	private String ccplayContentApiServer;

	@Value("${ccplay.commonservice.api.server}")
	private String ccplayCommonserviceApiServer;

	@Value("${ccplay.activity.api.server}")
	private String ccplayActivityApiServer;

	@Value("${ccplay.report.api.server}")
	private String ccplayReportApiServer;

	@Value("${ccplay.payment.api.server}")
	private String ccplayPaymentApiServer;

	@Value("${ccplay.order.api.server}")
	private String ccplayOrderApiServer;

	@Value("${nginx.key.regex}")
	protected String nginxKeyRegex;

	@Value("${alipay.partner}")
	public String alipayPartner;

	@Value("${alipay.rsa_private}")
	public String alipayRsaPrivate;

	@Value("${alipay.rsa_public}")
	public String alipayRsaPublic;

	@Value("${qqpay.key}")
	public String qqpayKey;

	@Value("${weixinpay.key}")
	protected String weixinpay_key;
	
	@Value("${weixinpay.v2.key}")
	protected String weixinpay_key_v2;
	
	@Value("${weixinpay.m.key}")
	protected String weixinpay_key_m;
	
	
	
	@Autowired
	protected TaskExecutor myExecutor;

	protected JsonObject extractClientEventFromHeader(HttpServletRequest req) {
		String xClientEvent = WebHelper.extractRequestHeader(req, "X-Client-Event");
		JsonObject jsonObj = JsonUtil.jsonToObject(xClientEvent, JsonObject.class);
		return jsonObj;
	}

	protected Map<String, Object> getParamMapFromRequest(HttpServletRequest req) {
		Map<String, Object> reqParamMap = WebHelper.buildParamMapFromRequest(req);
		reqParamMap.put(Constant.REQUEST_IP, WebHelper.getRequestIp(req));
		reqParamMap.put(Constant.USER_AGENT, WebHelper.extractRequestHeader(req, "User-Agent"));
		String authorization = WebHelper.extractRequestHeader(req, "Authorization");
		if (!StringUtils.isEmpty(authorization) && authorization.indexOf("Token") != -1) {
			reqParamMap.put(Constant.AUTH_TOKEN, authorization.replaceAll("Token ", ""));
		}
		return reqParamMap;
	}

	protected String callApi(ApiMethodEnum apiMethodEnum, Map<String, Object> reqParamMap) {
		if (!reqParamMap.containsKey(Constant.API_KEY)) {
			reqParamMap.put(Constant.API_KEY, defaultApiKey);
		}
		if (!reqParamMap.containsKey(Constant.ACCESS_TOKEN)) {
			reqParamMap.put(Constant.ACCESS_TOKEN, Constant.DEFAULT_ACCESS_TOKEN);
		}
		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put(apiMethodEnum.getCode(), reqParamMap);
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put(Constant.DATA, JsonUtil.objectToJson(dataMap, Map.class));
		HttpClientUtil clientUtil = new HttpClientUtil();
		Map<String, String> head = new HashMap<String, String>();
		int port = SuperDispatcherServlet.getlocalPort();
		head.put("referer", "dataservice/" + port);
		head.put("X-Hash-ip", (String) reqParamMap.get(Constant.REQUEST_IP));
		clientUtil.setHttpSetting(head);
		String retJson = clientUtil.doHttpPost(this.getApiServeUrl(apiMethodEnum.getApiServer()), paramMap);
		return retJson;
	}

	protected String getApiServeUrl(ApiServerEnum apiServerEnum) {
		if (ApiServerEnum.user.equals(apiServerEnum)) {
			return this.ccplayUserApiServer;
		} else if (ApiServerEnum.content.equals(apiServerEnum)) {
			return this.ccplayContentApiServer;
		} else if (ApiServerEnum.activity.equals(apiServerEnum)) {
			return this.ccplayActivityApiServer;
		} else if (ApiServerEnum.commonservice.equals(apiServerEnum)) {
			return this.ccplayCommonserviceApiServer;
		} else if (ApiServerEnum.report.equals(apiServerEnum)) {
			return this.ccplayReportApiServer;
		} else if (ApiServerEnum.payment.equals(apiServerEnum)) {
			return this.ccplayPaymentApiServer;
		} else if (ApiServerEnum.order.equals(apiServerEnum)) {
			return this.ccplayOrderApiServer;
		}
		return null;
	}

	protected String outputApiFinalResponse(String functionCode, ApiMsgEnum apiMsgEnum, HttpServletResponse rsp) {
		if (functionCode == null || "".equals(functionCode)) {
			functionCode = "unknown";
		}
		ApiFinalResponse<String> apiFinalRsp = new ApiFinalResponse<String>();
		apiFinalRsp.setIsSuccess(apiMsgEnum.getIsSuccess());
		apiFinalRsp.setCode(apiMsgEnum.getCode());
		apiFinalRsp.setMsg(apiMsgEnum.getMsg());
		Map<String, Object> jsonMap = new HashMap<String, Object>();
		jsonMap.put(functionCode, apiFinalRsp);
		String retJson = JsonUtil.objectToJson(jsonMap);
		return WebHelper.outputJson(retJson, rsp);
	}

	protected JsonObject buildSystemParamFromHeader(HttpServletRequest req) {
		JsonObject sysParamJsonObj = new JsonObject();
		String requestIp = WebHelper.getRequestIp(req);
		String userAgent = WebHelper.extractRequestHeader(req, "User-Agent");
		sysParamJsonObj.addProperty(Constant.REQUEST_IP, requestIp);
		sysParamJsonObj.addProperty(Constant.USER_AGENT, userAgent);
		JsonObject clientEventObj = this.extractClientEventFromHeader(req);
		boolean needSignSysParam = true;
		String idfa = null;
		String sysVer = null;
		String certId = null;
		String clientChannelCode = null;
		String clientBundleId = null;
		String clientVer = null;
		if (clientEventObj != null) {
			needSignSysParam = false;
			idfa = this.extractValueFromClientEvent(clientEventObj, Constant.IDFA);
			sysVer = this.extractValueFromClientEvent(clientEventObj, Constant.SYS_VER);
			certId = this.extractValueFromClientEvent(clientEventObj, Constant.CERT_ID);
			clientChannelCode = this.extractValueFromClientEvent(clientEventObj, Constant.CLIENT_CHANNEL_CODE);
			clientBundleId = this.extractValueFromClientEvent(clientEventObj, Constant.CLIENT_BUNDLE_ID);
			clientVer = this.extractValueFromClientEvent(clientEventObj, Constant.CLIENT_VER);
			sysParamJsonObj.addProperty(Constant.IDFA, idfa);
			sysParamJsonObj.addProperty(Constant.SYS_VER, sysVer);
			sysParamJsonObj.addProperty(Constant.CERT_ID, certId);
			sysParamJsonObj.addProperty(Constant.CLIENT_CHANNEL_CODE, clientChannelCode);
			sysParamJsonObj.addProperty(Constant.CLIENT_BUNDLE_ID, clientBundleId);
			sysParamJsonObj.addProperty(Constant.CLIENT_VER, clientVer);
		}
		sysParamJsonObj.addProperty(Constant.NEED_SIGN_SYSPARAM, needSignSysParam);
		return sysParamJsonObj;
	}

	private String extractValueFromClientEvent(JsonObject clientEventObj, String key) {
		if (clientEventObj.has(key)) {
			return clientEventObj.get(key).getAsString();
		}
		return null;
	}

	/**
	 * 记录nginx访问信息
	 * 
	 * @param request
	 */
	protected void saveNginxCacheInfo(final HttpServletRequest request, String codes, String key, final String result) {
		String url = request.getRequestURI();
		if (RegexUtil.checkIncluded(nginxKeyRegex, url)) {
			String data = request.getParameter(Constant.DATA);
			final String host = request.getServerName() + url;
			final Map<String, Object> reqParamMap = new HashMap<String, Object>();
			reqParamMap.put("codes", codes);
			reqParamMap.put("key", host);
			reqParamMap.put("nginxServer", request.getServerName());
			reqParamMap.put(Constant.DATA, data);
			myExecutor.execute(new Runnable() {
				@Override
				public void run() {
					// MemcachedUtil.getInstance().set(host, result);
					// callApi(ApiMethodEnum.BACKEND_NGINX_COLLECTNGINXCACHE,
					// reqParamMap);
				}
			});
		}
	}

	protected String outputJson(String json, HttpServletResponse response) {
		// response.reset();
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json;charset=UTF-8");
		try {
			PrintWriter out = response.getWriter();
			out.print(json);
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
